package org.qdao;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;
import java.util.logging.Logger;

import com.tan.util.StringUtil;
import com.tan.util.TanUtil;
/**
 * 
 * @author 譚元吉
 * @since 2010/02/06 11:00:50
 */
public class DBConfig {

	public String[] jarPath;

	public String driver;

	public String url;

	public String username;

	public String password;
	
	public String scanPackage;
	
	private Properties config;
	
	private String absolutPath;
	
	private String schema;
	
	private boolean autoDDL;
	
	private boolean autoCreateSchema;
	
	private boolean isLogger;
	
	private int defaultPageSize; //默认分页大小.
	
	
	private int maxPageSize; // 每页最大显示条数.
	
	private int maxPage; // 最大页码.
	
	/**
	 * @return the maxPage	最大页码.
	 */
	public int getMaxPage() {
		if ( maxPageSize < 500 ) {
			return 500;
		}
		return maxPage;
	}

	/**
	 * @return the maxPageSize	每页最大显示条数
	 */
	public int getMaxPageSize() {
		if ( maxPageSize < 200 ) {
			return 200;
		}
		return maxPageSize;
	}

	
	private Logger logger = Logger.getLogger( this.getClass().getName() );

	private static DBConfig instance;
	
	public static DBConfig getInstance() {
		if (null == instance) {
			synchronized (DBConfig.class) {
				if (null == instance) {
					instance = new DBConfig();
				}
			}
		}
		return instance;
	}

	public static DBConfig getInstance(final String path) {
		if (null == instance) {
			synchronized (DBConfig.class) {
				if (null == instance) {
					instance = new DBConfig(path);
				}
			}
		}
		return instance;
	}
	
	private DBConfig() {
		this("db.config");
	}
	
	private DBConfig(final String fileName) {
		config = new Properties();
		absolutPath = DBConfig.class.getResource('/' + fileName).getFile();
		InputStream in = DBConfig.class.getResourceAsStream('/' + fileName);
		try {
			config.load(in);
		} catch (Throwable e) {
			System.err.println("未找到数据库配置文件:" + DBConfig.class.getResource("").getFile() + fileName);
		} finally {
			if (null != in) {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				} in = null;
			}
		}
		
		initConfig();
	}
	
	public boolean save() {
		return save("");
	}
	
	public boolean save(final String comments) {
		if (null == absolutPath) return false;
		else {
			if (absolutPath.indexOf("%20") >= 0){
				absolutPath = absolutPath.replaceAll("%20", " ");
			}
		}
		// to save the stream.
		OutputStream out = null;
		try {
			out = new FileOutputStream(absolutPath);
			config.store(new FileOutputStream(absolutPath), comments);
		} catch (FileNotFoundException e) {
			e.printStackTrace(); return false;
		} catch (IOException e) {
			e.printStackTrace(); return false;
		} finally {
			if (null != out) {
				try {
					out.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			} out = null;
		}
		return true;
	}
	
	private void initConfig() {
		username = (String) config.getProperty("username");
		driver =(String)  config.getProperty("driver");
		url =(String)  config.getProperty("url");
		int idx = url.lastIndexOf('/');
		if (idx >= 0) {
		    schema = url.substring(idx + 1);
		}
		password =(String)  config.getProperty("password");
		scanPackage = (String) config.getProperty("scan.package.model");
		jarPath = new String[]{(String) config.getProperty("jarPath")};
		checkJarPath();
		autoDDL = Boolean.valueOf(config.getProperty("autoDDL"));
		autoCreateSchema = Boolean.valueOf(config.getProperty("autoCreateSchema"));
		isLogger = Boolean.valueOf(config.getProperty( "isLogger" ));
		defaultPageSize = Integer.valueOf(config.getProperty("defaultPageSize"));
		maxPageSize = Integer.valueOf(config.getProperty("maxPageSize"));
		maxPage = Integer.valueOf(config.getProperty("maxPage"));
	}
	
	/**
	 * 获取对应 key 的值.
	 * @param key
	 * @return
	 */
	public Object get( final String key ) {
		if ( null == config ) {
			return null;
		}
		return config.get( key );
	}
	
	/**
	 * 是否存在Jar Path
	 */
	private void checkJarPath() {
		Class<?> ignoreClz = null;
		try {
			ignoreClz = Class.forName( driver );
		} catch (ClassNotFoundException e) {
		}
		if (null != ignoreClz )  {
			log( "驱动类加载成功(当前 ClassLoader )!忽略检验" );
			// ignore check jar path.
			return;
		} else {
			log( "驱动类加载未成功(当前 ClassLoader )!" );
		}
		
		/**------------------**/
		if (null == jarPath || jarPath.length == 0) {
			log("未加载JarPath,重加载启动");
			reloadJarPath();
		} else {
			final String path = jarPath[0];
			if (StringUtil.isEmpty(path) || !path.toLowerCase().endsWith(".jar")) {
				log("不是一个有效的jar文件路径,重加载启动");
				reloadJarPath();
			} else {
				final File file = new File(path) ;
				if (!file.exists()) {
					log(file + " 文件不存在,重加载启动");
					reloadJarPath();
				} else if(file.isDirectory())  {
					log(file + " 文件是一个目录,重加载启动");
					reloadJarPath();
				}
			}
		}
	}
	
	
	public boolean validateJarPath() {
		if (null == jarPath || jarPath.length == 0) {
			return false;
		} else {
			final String path = jarPath[0];
			if (StringUtil.isEmpty(path) || !path.toLowerCase().endsWith(".jar")) {
				return false;
			} else {
				final File file = new File(path) ;
				if (!file.exists()) {
					return false;
				} else if(file.isDirectory())  {
					return false;
				}
			}
		}
		return true;
	}
	
	private void log( final Object msg ) {
		if ( isLogger ) {
			logger.info( String.valueOf( msg ) );
		}
	}
	
	/**
	 * 设置Jdbc包. jar 
	 */
	private void reloadJarPath() {
		final File file = TanUtil.chooseJarFile("d:\\", "请选择一个有效的jdbc包");
		if (null != file && file.isFile() && file.getName().toLowerCase().endsWith(".jar")) {
			final String path = file.getAbsolutePath();
			jarPath = new String[]{path};
			config.setProperty("jarPath", path);
			save();
		} else {
			checkJarPath();
		}
	}

	public boolean isConfig() {
		if (null == jarPath || jarPath.length < 1) {
			System.err.println("数据库JAR包未配置!");
			return false;
		}
		if (StringUtil.isEmpty(driver)) {
			System.err.println("数据库Driver的Class未配置!");
			return false;
		}
		if (StringUtil.isEmpty(url)) {
			System.err.println("数据库连接URL为空!");
			return false;
		}
		if (StringUtil.isEmpty(username)) {
			System.err.println("数据库用户名为空!");
			return false;
		}
		if (StringUtil.isEmpty(password)) {
			System.err.println("数据库密码为空!");
			return false;
		}
		
		return true;
	}

	public static void main(String []args) {
		DBConfig config = new DBConfig();
		if (config.isConfig()) {
			System.out.println("数据库配置成功!");
		}
	}

	public void setUrl(String url) {
		this.url = url;
		config.setProperty("url", url);
	}

    public String getSchema()
    {
        return schema;
    }

    public void setSchema(String schema)
    {
        this.schema = schema;
		int idx = url.lastIndexOf('/');
		if (idx >= 0) {
			setUrl(url.substring(0, idx + 1) + schema);
		}
    }

    public boolean isAutoDDL()
    {
        return autoDDL;
    }

    public void setAutoDDL(boolean autoDDL)
    {
        this.autoDDL = autoDDL;
    }

	public boolean isAutoCreateSchema() {
		return autoCreateSchema;
	}

	public void setAutoCreateSchema(boolean autoCreateSchema) {
		this.autoCreateSchema = autoCreateSchema;
	}

	public boolean isLogSql() {
		return isLogger;
	}

	public void setLogSql(boolean logSql) {
		this.isLogger = logSql;
	}

	public int getDefaultPageSize() {
		return defaultPageSize;
	}

	public boolean isLogger() {
		return isLogger;
	}

	public void setLogger(boolean isLogger) {
		this.isLogger = isLogger;
	}

	
}
